home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / GENCTXT.ZIP / CHAP12.TXT < prev    next >
Text File  |  1987-11-21  |  27KB  |  587 lines

  1.  
  2.                       Chapter 12 - Dynamic Allocation
  3.  
  4.  
  5.                         WHAT IS DYNAMIC ALLOCATION?
  6.  
  7.              Dynamic allocation is very intimidating to a person the
  8.         first time he comes across it, but that need not be.  Simply
  9.         relax  and  read this chapter carefully and you will have  a
  10.         good grounding in a very valuable programming resource.  All
  11.         of the variables in every program up to this point have been
  12.         static  variables as far as we  are  concerned.   (Actually,
  13.         some  of  them  have been "automatic" and  were  dynamically
  14.         allocated for you by the system,  but it was transparent  to
  15.         you.)   In  this  chapter,  we will study  some  dynamically
  16.         allocated  variables.  They are variables that do not  exist
  17.         when  the program is loaded, but are created dynamically  as
  18.         they are needed.  It is possible, using these techniques, to
  19.         create as many variables as needed, use them, and deallocate
  20.         their space for use by other variables.  As usual, the  best
  21.         teacher is an example, so load and display the program named
  22.         DYNLIST.C.
  23.  
  24.              We  begin by defining a named structure "animal" with a
  25.         few  fields  pertaining  to dogs.   We  do  not  define  any
  26.         variables of this type,  only three pointers.  If you search
  27.         through  the  remainder  of the program,  you will  find  no
  28.         variables defined so we have nothing to store data in.   All
  29.         we have to work with are three pointers, each of which point
  30.         to the defined structure.   In order to do anything, we need
  31.         some variables, so we will create some dynamically.
  32.  
  33.                          DYNAMIC VARIABLE CREATION
  34.  
  35.              The first program statement, which assigns something to
  36.         the   pointer  "pet1"  will  create  a   dynamic   structure
  37.         containing  three variables.   The heart of the statement is
  38.         the "malloc" function buried in the middle of the statement.
  39.         This  is a "memory allocate" function that needs  the  other
  40.         things to completely define it.   The "malloc" function,  by
  41.         default, will allocate a piece of memory on a "heap" that is
  42.         "n" characters in length and will be of type character.  The
  43.         "n"  must be specified as the only argument to the function.
  44.         We will discuss "n" shortly,  but first we need to define  a
  45.         "heap".
  46.  
  47.                               WHAT IS A HEAP?
  48.  
  49.              Every compiler has a set of limitations on it as to how
  50.         big  the executable file can be,  how many variables can  be
  51.         used,  how long the source file can be, etc.  One limitation
  52.         placed  on users by most C compilers is a limit of  64K  for
  53.         the executable code if you happen to be in the small  memory
  54.         model.   This  is because the IBM-PC uses  a  microprocessor
  55.         with  a 64K segment size, and it requires special  calls  to
  56.  
  57.  
  58.                                   Page 87
  59.  
  60.  
  61.  
  62.  
  63.  
  64.  
  65.  
  66.  
  67.  
  68.                       Chapter 12 - Dynamic Allocation
  69.  
  70.  
  71.         use data outside of a single segment.  In order to keep  the
  72.         program  small and efficient, these calls are not used,  and
  73.         the  memory  space is limited but still  adequate  for  most
  74.         programs.
  75.  
  76.              A  heap is an area outside of this 64K  boundary  which
  77.         can be accessed by the program to store data and  variables.
  78.         The  data and variables are put on the "heap" by the  system
  79.         as  calls to "malloc" are made.  The system keeps  track  of
  80.         where  the  data  is  stored.  Data  and  variables  can  be
  81.         deallocated  as desired leading to holes in the  heap.   The
  82.         system  knows  where  the holes are and will  use  them  for
  83.         additional  data  storage as more "malloc" calls  are  made.
  84.         The  structure  of  the heap is  therefore  a  very  dynamic
  85.         entity, changing constantly.
  86.  
  87.                             MORE ABOUT SEGMENTS
  88.  
  89.              Most  C  compilers  give the user a  choice  of  memory
  90.         models to use. The user has a choice of using a model with a
  91.         64K limitation for either program or data leading to a small
  92.         fast  program or selecting a 640K limitation  and  requiring
  93.         longer  address calls leading to less efficient  addressing.
  94.         Using  the  larger  address  space  requires  inter  segment
  95.         addressing,  resulting in the slightly slower running  time.
  96.         The  time  is probably insignificant in most  programs,  but
  97.         there are other considerations.
  98.  
  99.              If a program uses no more than 64K bytes for the  total
  100.         of its code and memory and if it doesn't use a stack, it can
  101.         be made into a .COM file.  Since a .COM file is already in a
  102.         memory image format, it can be loaded very quickly whereas a
  103.         file in an .EXE format must have its addresses relocated  as
  104.         it is loaded.  Therefore a tiny memory model can generate  a
  105.         program  that loads faster than one generated with a  larger
  106.         memory model.  Don't let this worry you, it is a fine  point
  107.         that few programmers worry about.
  108.  
  109.              Using  dynamic allocation, it is possible to store  the
  110.         data  on the "heap" and that may be enough to allow  you  to
  111.         use  the small memory model.  Of course, you wouldn't  store
  112.         local  variables such as counters and indexes on  the  heap,
  113.         only very large arrays or structures.
  114.  
  115.              Even  more  important than the need to stay within  the
  116.         small memory model is the need to stay within the  computer.
  117.         If  you  had a program that used several large data  storage
  118.         areas,  but not at the same time,  you could load one  block
  119.         storing  it  dynamically,  then get rid of it and reuse  the
  120.         space for the next large block of data.  Dynamically storing
  121.         each block of data in succession, and using the same storage
  122.  
  123.  
  124.                                   Page 88
  125.  
  126.  
  127.  
  128.  
  129.  
  130.  
  131.  
  132.  
  133.  
  134.                       Chapter 12 - Dynamic Allocation
  135.  
  136.  
  137.         for  each block may allow you to run your entire program  in
  138.         the computer without breaking it up into smaller programs.
  139.  
  140.                        BACK TO THE "MALLOC" FUNCTION
  141.  
  142.              Hopefully  the above description of the "heap" and  the
  143.         overall plan for dynamic allocation helped you to understand
  144.         what  we are doing with the "malloc"  function.   It  simply
  145.         asks the system for a block of memory of the size specified,
  146.         and  gets  the block with the pointer pointing to the  first
  147.         element of the block.   The only argument in the parentheses
  148.         is the size of the block desired and in our present case, we
  149.         desire  a  block  that will hold one of  the  structures  we
  150.         defined at the beginning of the program.  The "sizeof" is  a
  151.         new  function, new to us at least, that returns the size  in
  152.         bytes of the argument within its parentheses.  It therefore,
  153.         returns the size of the structure named "animal", in  bytes,
  154.         and  that  number is sent to the system  with  the  "malloc"
  155.         call.   At the completion of that call, we have a  block  on
  156.         the heap allocated to us, with "pet1" pointing to the  block
  157.         of data.
  158.  
  159.                               WHAT IS A CAST?
  160.  
  161.              We  still  have  a  funny  looking  construct  at   the
  162.         beginning  of the "malloc" function call.   That is called a
  163.         "cast".   The  "malloc"  function returns a block  with  the
  164.         pointer  pointing  to it being a pointer of type  "char"  by
  165.         default.  Many times, if not most, you do not want a pointer
  166.         to a "char" type variable,  but to some other type.  You can
  167.         define  the  pointer type with the construct  given  on  the
  168.         example line.   In this case we want the pointer to point to
  169.         a  structure of type "animal",  so we tell the compiler with
  170.         this strange looking construct.   Even if you omit the cast,
  171.         most compilers will return a pointer correctly,  give you  a
  172.         warning,  and  go  on to produce a working program.   It  is
  173.         better programming practice to provide the compiler with the
  174.         cast to prevent getting the warning message.
  175.  
  176.                 USING THE DYNAMICALLY ALLOCATED MEMORY BLOCK
  177.  
  178.              If you remember our studies of structures and pointers,
  179.         you  will recall that if we have a structure with a  pointer
  180.         pointing  to it,  we can access any of the variables  within
  181.         the structure.   In the next three lines of the program,  we
  182.         assign  some silly data to the structure  for  illustration.
  183.         It  should come as no surprise to you that these  assignment
  184.         statements  look just like assignments to statically defined
  185.         variables.
  186.  
  187.  
  188.  
  189.  
  190.                                   Page 89
  191.  
  192.  
  193.  
  194.  
  195.  
  196.  
  197.  
  198.  
  199.  
  200.                       Chapter 12 - Dynamic Allocation
  201.  
  202.  
  203.              In the next statement, we assign the value of "pet1" to
  204.         "pet2" also.   This creates no new data,  we simply have two
  205.         pointers  to the same object.   Since "pet2" is pointing  to
  206.         the structure we created above,  "pet1" can be reused to get
  207.         another  dynamically allocated structure which is just  what
  208.         we  do next.   Keep in mind that "pet2" could have  just  as
  209.         easily been used for the new allocation.   The new structure
  210.         is filled with silly data for illustration.
  211.  
  212.              Finally,  we  allocate another block on the heap  using
  213.         the  pointer  "pet3",  and fill its block with  illustrative
  214.         data.
  215.  
  216.              Printing  the  data out should pose no problem  to  you
  217.         since  there is nothing new in the three  print  statements.
  218.         It is left for you to study.
  219.  
  220.              Even though it is not illustrated in this tutorial, you
  221.         can dynamically allocate and use simple variables such as  a
  222.         single  "char"  type variable.  This should  be  discouraged
  223.         however since it is very inefficient.
  224.  
  225.                GETTING RID OF THE DYNAMICALLY ALLOCATED DATA
  226.  
  227.              Another new function is used to get rid of the data and
  228.         free  up  the  space on the heap  for  reuse,  the  function
  229.         "free".   To use it,  you simply call it with the pointer to
  230.         the   block  as  the  only  argument,   and  the  block   is
  231.         deallocated.
  232.  
  233.              In  order  to illustrate another aspect of the  dynamic
  234.         allocation and deallocation of data,  an additional step  is
  235.         included in the program on your monitor.  The pointer "pet1"
  236.         is assigned the value of "pet3" in line 38.  In doing  this,
  237.         the  block that "pet1" was pointing to is  effectively  lost
  238.         since  there  is  no pointer that is now  pointing  to  that
  239.         block.   It  can  therefore  never  again  be  referred  to,
  240.         changed,  or disposed of.  That memory, which is a block  on
  241.         the  heap,  is  wasted  from this point  on.   This  is  not
  242.         something that you would ever purposely do in a program.  It
  243.         is only done here for illustration.
  244.  
  245.              The  first  "free" function call removes the  block  of
  246.         data that "pet1" and "pet3" were pointing to, and the second
  247.         "free"  call  removes  the block of  data  that  "pet2"  was
  248.         pointing  to.   We therefore have lost access to all of  our
  249.         data  generated earlier.   There is still one block of  data
  250.         that  is on the heap but there is no pointer to it since  we
  251.         lost  the address to it.   Trying to "free" the data pointed
  252.         to by "pet1" would result in an error because it has already
  253.         been  "freed"  by the use of "pet3".  There is  no  need  to
  254.  
  255.  
  256.                                   Page 90
  257.  
  258.  
  259.  
  260.  
  261.  
  262.  
  263.  
  264.  
  265.  
  266.                       Chapter 12 - Dynamic Allocation
  267.  
  268.  
  269.         worry,  when  we  return to DOS, the  entire  heap  will  be
  270.         disposed  of with no regard to what we have put on it.   The
  271.         point  does  need to made that, if you lose a pointer  to  a
  272.         block  of  the heap, it forever removes that block  of  data
  273.         storage from our use and we may need that storage later.
  274.  
  275.              Compile and run the program to see if it does what  you
  276.         think it should do based on this discussion.
  277.  
  278.                         THAT WAS A LOT OF DISCUSSION
  279.  
  280.              It took nearly four pages to get through the discussion
  281.         of  the last program but it was time well spent.   It should
  282.         be  somewhat exciting to you to know that there  is  nothing
  283.         else to learn about dynamic allocation,  the last four pages
  284.         covered  it all.   Of course,  there is a lot to learn about
  285.         the  technique  of using dynamic allocation,  and  for  that
  286.         reason,  there  are two more files to study.   But the  fact
  287.         remains,  there  is  nothing  more to  learn  about  dynamic
  288.         allocation than what was given so far in this chapter.
  289.  
  290.                             AN ARRAY OF POINTERS
  291.  
  292.              Load and display the file BIGDYNL.C for another example
  293.         of dynamic allocation.   This program is very similar to the
  294.         last one since we use the same structure,  but this time  we
  295.         define an array of pointers to illustrate the means by which
  296.         you  could build a large database using an array of pointers
  297.         rather  than a single pointer to each element.   To keep  it
  298.         simple  we  define  12 elements in  the  array  and  another
  299.         working pointer named "point".
  300.  
  301.              The "*pet[12]" is new to you so a few words would be in
  302.         order.  What we have defined is an array of 12 pointers, the
  303.         first  being "pet[0]",  and the last  "pet[11]".   Actually,
  304.         since an array is itself a pointer, the name "pet" by itself
  305.         is a pointer to a pointer.   This is valid in C, and in fact
  306.         you  can  go  farther  if needed but you  will  get  quickly
  307.         confused.   I  know  of no limit as to how  many  levels  of
  308.         pointing are possible,  so a definition such as "int ****pt"
  309.         is legal as a pointer to a pointer to a pointer to a pointer
  310.         to an integer type variable, if I counted right.  Such usage
  311.         is discouraged until you gain considerable experience.
  312.  
  313.              Now that we have 12 pointers which can be used like any
  314.         other  pointer,  it  is a simple matter to write a  loop  to
  315.         allocate  a data block dynamically for each and to fill  the
  316.         respective  fields with any data desirable.   In this  case,
  317.         the  fields  are  filled with simple data  for  illustrative
  318.         purposes,  but we could be reading in a  database,  readings
  319.         from some test equipment, or any other source of data.
  320.  
  321.  
  322.                                   Page 91
  323.  
  324.  
  325.  
  326.  
  327.  
  328.  
  329.  
  330.  
  331.  
  332.                       Chapter 12 - Dynamic Allocation
  333.  
  334.  
  335.  
  336.              A  few fields are randomly picked to receive other data
  337.         to illustrate that simple assignments can be used,  and  the
  338.         data is printed out to the monitor.   The pointer "point" is
  339.         used  in the printout loop only to serve as an illustration,
  340.         the  data could have been easily printed using the  "pet[n]"
  341.         means  of definition.   Finally,  all 12 blocks of data  are
  342.         freed before terminating the program.
  343.  
  344.              Compile  and run this program to aid  in  understanding
  345.         this  technique.   As stated earlier,  there was nothing new
  346.         here  about  dynamic  allocation,  only about  an  array  of
  347.         pointers.
  348.  
  349.                                A LINKED LIST
  350.  
  351.              We  finally  come to the grandaddy of  all  programming
  352.         techniques as far as being intimidating.   Load the  program
  353.         DYNLINK.C  for an example of a dynamically allocated  linked
  354.         list.   It  sounds terrible,  but after a little time  spent
  355.         with it,  you will see that it is simply another programming
  356.         technique  made  up  of  simple components  that  can  be  a
  357.         powerful tool.
  358.  
  359.              In order to set your mind at ease,  consider the linked
  360.         list  you used when you were a child.   Your sister gave you
  361.         your birthday present,  and when you opened it,  you found a
  362.         note that said,  "Look in the hall closet."  You went to the
  363.         hall closet,  and found another note that said, "Look behind
  364.         the  TV  set."  Behind the TV you found  another  note  that
  365.         said,  "Look  under  the  coffee pot."  You  continued  this
  366.         search,  and finally you found your pair of socks under  the
  367.         dogs  feeding dish.   What you actually did was to execute a
  368.         linked  list,  the starting point being the wrapped  present
  369.         and the ending point being under the dogs feeding dish.  The
  370.         list ended at the dogs feeding dish since there were no more
  371.         notes.
  372.  
  373.              In  the program DYNLINK.C,  we will be doing  the  same
  374.         thing as your sister forced you to do.   We will however, do
  375.         it  much  faster and we will leave a little pile of data  at
  376.         each of the intermediate points along the way.  We will also
  377.         have   the  capability  to  return  to  the  beginning   and
  378.         retraverse the entire list again and again if we so desire.
  379.  
  380.                             THE DATA DEFINITIONS
  381.  
  382.              This program starts similarly to the last two with  the
  383.         addition  of the definition of a constant to be used  later.
  384.         The  structure  is nearly the same as that used in the  last
  385.         two programs except for the addition of another field within
  386.  
  387.  
  388.                                   Page 92
  389.  
  390.  
  391.  
  392.  
  393.  
  394.  
  395.  
  396.  
  397.  
  398.                       Chapter 12 - Dynamic Allocation
  399.  
  400.  
  401.         the  structure in line 11, the pointer.  This pointer  is  a
  402.         pointer  to another structure of this same type and will  be
  403.         used  to point to the next structure in order.  To  continue
  404.         the above analogy, this pointer will point to the next note,
  405.         which in turn will contain a pointer to the next note  after
  406.         that.
  407.  
  408.              We  define three pointers to this structure for use  in
  409.         the program, and one integer to be used as a counter, and we
  410.         are ready to begin using the defined structure for  whatever
  411.         purpose  we  desire.   In  this case,  we  will  once  again
  412.         generate nonsense data for illustrative purposes.
  413.  
  414.                               THE FIRST FIELD
  415.  
  416.              Using  the  "malloc" function,  we request a  block  of
  417.         storage on the "heap" and fill it with data.  The additional
  418.         field in this example, the pointer, is assigned the value of
  419.         NULL, which is only used to indicate that this is the end of
  420.         the  list.   We  will  leave  the pointer  "start"  at  this
  421.         structure,  so  that  it  will always  point  to  the  first
  422.         structure of the list.   We also assign "prior" the value of
  423.         "start" for reasons we will see soon.  Keep in mind that the
  424.         end  points of a linked list will always have to be  handled
  425.         differently  than those in the middle of a list.   We have a
  426.         single  element  of  our  list now and  it  is  filled  with
  427.         representative data.
  428.  
  429.                        FILLING ADDITIONAL STRUCTURES
  430.  
  431.              The  next group of assignments and  control  statements
  432.         are  included  within a "for" loop so we can build our  list
  433.         fast  once  it is defined.   We will go through the  loop  a
  434.         number  of times equal to the constant "RECORDS" defined  at
  435.         the  beginning  of  our  program.   Each  time  through,  we
  436.         allocate memory,  fill the first three fields with nonsense,
  437.         and  fill the pointers.   The pointer in the last record  is
  438.         given  the  address of this new record because  the  "prior"
  439.         pointer is pointing to the prior record.  Thus "prior->next"
  440.         is given the address of the new record we have just  filled.
  441.         The  pointer in the new record is assigned the value "NULL",
  442.         and  the  pointer "prior" is given the address of  this  new
  443.         record  because the next time we create a record,  this  one
  444.         will  be  the  prior  one at  that  time.   That  may  sound
  445.         confusing  but it really does make sense if you  spend  some
  446.         time studying it.
  447.  
  448.              When  we have gone through the "for" loop 6  times,  we
  449.         will  have  a  list  of 7 structures including  the  one  we
  450.         generated  prior  to  the loop.   The  list  will  have  the
  451.         following characteristics.
  452.  
  453.  
  454.                                   Page 93
  455.  
  456.  
  457.  
  458.  
  459.  
  460.  
  461.  
  462.  
  463.  
  464.                       Chapter 12 - Dynamic Allocation
  465.  
  466.  
  467.  
  468.  
  469.         1. "start" points to the first structure in the list.
  470.  
  471.         2. Each structure contains a pointer to the next structure.
  472.  
  473.         3. The last structure has a pointer  that points to NULL and
  474.            can be used to detect the end.
  475.  
  476.            start->struct1              This diagram should aid in
  477.                   name              understanding the structure of
  478.                   breed             the data at this point.
  479.                   age
  480.                   point->struct2
  481.                          name
  482.                          breed
  483.                          age
  484.                          point->struct3
  485.                                 name
  486.                                 breed
  487.                                 age
  488.                                 point-> . . . . struct7
  489.                                                 name
  490.                                                 breed
  491.                                                 age
  492.                                                 point->NULL
  493.  
  494.  
  495.              It should be clear to you,  if you understand the above
  496.         structure,  that  it is not possible to simply jump into the
  497.         middle of the structure and change a few values.   The  only
  498.         way  to  get  to the third structure is by starting  at  the
  499.         beginning  and working your way down through  the  structure
  500.         one  record at a time.   Although this may seem like a large
  501.         price  to  pay for the convenience of putting so  much  data
  502.         outside of the program area,  it is actually a very good way
  503.         to store some kinds of data.
  504.  
  505.             A  word processor would be a good application  for  this
  506.         type  of data structure because you would never need to have
  507.         random access to the data.   In actual practice, this is the
  508.         basic type of storage used for the text in a word  processor
  509.         with one line of text per record.   Actually, a program with
  510.         any degree of sophistication would use a doubly linked list.
  511.         This  would  be  a list with two pointers  per  record,  one
  512.         pointing down to the next record,  and the other pointing up
  513.         to the record just prior to the one in question.  Using this
  514.         kind  of a record structure would allow traversing the  data
  515.         in either direction.
  516.  
  517.  
  518.  
  519.  
  520.                                   Page 94
  521.  
  522.  
  523.  
  524.  
  525.  
  526.  
  527.  
  528.  
  529.  
  530.                       Chapter 12 - Dynamic Allocation
  531.  
  532.  
  533.                            PRINTING THE DATA OUT
  534.  
  535.              To print the data out, a similar method is used as that
  536.         used to generate the data.  The pointers are initialized and
  537.         are  then  used  to go from record  to  record  reading  and
  538.         displaying   each  record  one  at  a  time.    Printing  is
  539.         terminated when the NULL on the last record is found, so the
  540.         program  doesn't even need to know how many records  are  in
  541.         the list.   Finally, the entire list is deleted to make room
  542.         in  memory  for any additional data that may be  needed,  in
  543.         this case, none.  Care must be taken to assure that the last
  544.         record is not deleted before the NULL is checked.   Once the
  545.         data is gone,  it is impossible to know if you are  finished
  546.         yet.
  547.  
  548.                MORE ABOUT DYNAMIC ALLOCATION AND LINKED LISTS
  549.  
  550.              It  is  not difficult,  and it is not trivial,  to  add
  551.         elements into the middle of a linked lists.  It is necessary
  552.         to create the new record,  fill it with data,  and point its
  553.         pointer to the record it is desired to precede.   If the new
  554.         record  is  to be installed between the  3rd  and  4th,  for
  555.         example,  it is necessary for the new record to point to the
  556.         4th record,  and the pointer in the 3rd record must point to
  557.         the new one.  Adding a new record to the beginning or end of
  558.         a  list are each special cases.   Consider what must be done
  559.         to add a new record in a doubly linked list.
  560.  
  561.              Entire books are written describing different types  of
  562.         linked lists and how to use them,  so no further detail will
  563.         be  given.   The amount of detail given should be sufficient
  564.         for a beginning understanding of C and its capabilities.
  565.  
  566.                        ANOTHER NEW FUNCTION - CALLOC
  567.  
  568.              One  more  function must  be  mentioned,  the  "calloc"
  569.         function.   This  function  allocates a block of memory  and
  570.         clears  it  to  all  zeros  which  may  be  useful  in  some
  571.         circumstances.   It is similar to "malloc" and will be  left
  572.         as an exercise for you to read about and use "calloc" if you
  573.         desire.
  574.  
  575.         PROGRAMMING EXERCISES
  576.  
  577.         1.  Rewrite the example program STRUCT1.C from chapter 11 to
  578.             dynamically allocate the two structures.
  579.  
  580.         2.  Rewrite the example program STRUCT2.C from chapter 11 to
  581.             dynamically allocate the 12 structures.
  582.  
  583.  
  584.  
  585.  
  586.                                   Page 95
  587.